package info.rflow.model;

import info.rflow.Utils;
import info.rflow.connectors.ConnectorUtils;

import java.io.*;


/**
 * A thin layer connection to R which tracking the execution status of nodes
 *
 * @author Holger Brandl
 */
public class ROutputListener {

    private static StringBuilder sb = new StringBuilder();
    public static String RFLOW_MNUM_SUFFIX = "; \n ## rflow: block-end";
    private static File sinkFile;


    /**
     * @return true if initialization worked
     */
    public static boolean initialize() {
        try {
            sinkFile = File.createTempFile("rsink", ".txt");
            sinkFile.deleteOnExit();

            if (sinkFile.exists() && sinkFile.length() != 0)
                return true;

            // redirect all r-output into a file
            ConnectorUtils.push2R("sink(file='" + sinkFile.getAbsolutePath() + "', split=T);");

            new Thread() {
                @Override
                public void run() {
                    super.run();

                    try {

                        BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(sinkFile)));
                        while (true) {
                            while (!bf.ready()) {
                                sleep(100);
                            }

                            sb.append(bf.readLine());
                        }

                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }.start();
            return true;


        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }


    public static String addMNumSuffix(String codeBlock, int magicNumber) {
        return codeBlock + magicNumber + RFLOW_MNUM_SUFFIX;
    }


    public static void wait4MagicNumberOrTimeout(int magicNumber) {
        int maxSleepTime = 60000, sleepTime = 250;
        while (!sb.toString().contains(magicNumber + "") && maxSleepTime > 0) {
            maxSleepTime -= sleepTime;
            Utils.sleep(sleepTime);
        }

        sb = new StringBuilder();
    }


    public static void main(String[] args) {
        ROutputListener.initialize();


        final int magicNumber = Utils.getRanGen().nextInt();

        new Thread() {
            @Override
            public void run() {
                try {
                    sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                ConnectorUtils.push2R(addMNumSuffix("1+1; ", magicNumber));
            }
        }.start();

        ROutputListener.wait4MagicNumberOrTimeout(magicNumber);
        System.err.println("done");
    }

}
